package com.xbongbong.paas.service.team;

import com.alibaba.fastjson.JSON;
import com.xbongbong.crm.help.CrmTeamPermissionHelp;
import com.xbongbong.formula.constant.Constant;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.FieldTypeEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.help.BusinessUserTeamHelp;
import com.xbongbong.paas.help.FormDataHelp;
import com.xbongbong.paas.help.team.FormTeamSetHelp;
import com.xbongbong.paas.pojo.AddMuchFieldPojo;
import com.xbongbong.paas.pojo.dto.FormDataListDTO;
import com.xbongbong.paas.redis.RedisPrefixConstant;
import com.xbongbong.paas.service.dynamic.crm.strategy.DynamicStrategyFactory;
import com.xbongbong.paas.service.dynamic.crm.strategy.TeamDynamicStrategy;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.parent.factory.TeamDataFactory;
import com.xbongbong.parent.interfaces.TeamStrategy;
import com.xbongbong.pro.detailtab.dto.team.TeamDetailDTO;
import com.xbongbong.pro.detailtab.dto.team.TeamDetailEditLabelDTO;
import com.xbongbong.pro.detailtab.dto.team.TeamDetailUpdateDTO;
import com.xbongbong.pro.detailtab.pojo.team.MainUserPojo;
import com.xbongbong.pro.detailtab.pojo.team.ShareUserPermissionPojo;
import com.xbongbong.pro.detailtab.pojo.team.TeamUserPojo;
import com.xbongbong.pro.detailtab.vo.team.TeamDetailEditCoPerVO;
import com.xbongbong.pro.detailtab.vo.team.TeamDetailEditLabelVO;
import com.xbongbong.pro.detailtab.vo.team.TeamDetailShareVO;
import com.xbongbong.pro.detailtab.vo.team.TeamDetailVO;
import com.xbongbong.pro.detailtab.vo.team.TeamListBatchPermissionVO;
import com.xbongbong.pro.domain.entity.FormTeamSetEntity;
import com.xbongbong.pro.dynamic.pojo.dto.DynamicTeamDTO;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.pro.enums.UpdateCustomerTeamScenesEnum;
import com.xbongbong.pro.enums.errorcodes.UserTeamErrorCodeEnum;
import com.xbongbong.pro.enums.permission.enums.HandoverPermissionAliasEnum;
import com.xbongbong.pro.enums.teammembers.enums.CoUserPermissionEnum;
import com.xbongbong.pro.enums.teammembers.enums.FormPatternEnum;
import com.xbongbong.pro.formdata.pojo.AfterSavePojo;
import com.xbongbong.pro.formdata.pojo.SaasNeedRedundantAttrPojo;
import com.xbongbong.pro.listbatch.pojo.TeamBatchPojo;
import com.xbongbong.pro.team.TeamAfterVerifyDTO;
import com.xbongbong.pro.team.TeamLinkPOJO;
import com.xbongbong.pro.team.TeamUpdateMidPOJO;
import com.xbongbong.pro.team.TeamVerifyDTO;
import com.xbongbong.pro.team.pojo.TeamSaveMiddlePojo;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.constant.teammembers.TeamMembersConstant;
import com.xbongbong.saas.domain.entity.CustomerUserEntity;
import com.xbongbong.saas.domain.entity.PayPlanSheetUserEntity;
import com.xbongbong.saas.domain.entity.PaymentSheetUserEntity;
import com.xbongbong.saas.domain.entity.UserTeamEntity;
import com.xbongbong.saas.domain.entity.ext.AssembleEntityExt;
import com.xbongbong.saas.domain.entity.ext.InstockEntityExt;
import com.xbongbong.saas.domain.entity.ext.InventoryEntityExt;
import com.xbongbong.saas.domain.entity.ext.OutstockEntityExt;
import com.xbongbong.saas.domain.entity.ext.PayPlanSheetEntityExt;
import com.xbongbong.saas.domain.entity.ext.PaymentSheetEntityExt;
import com.xbongbong.saas.domain.entity.ext.ReturnedPurchaseEntityExt;
import com.xbongbong.saas.domain.entity.ext.TransferEntityExt;
import com.xbongbong.saas.enums.RedundantTemplateTypeEnum;
import com.xbongbong.saas.enums.SheetAloneEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.PaymentSheetEnum;
import com.xbongbong.saas.model.AssembleModel;
import com.xbongbong.saas.model.ClueUserModel;
import com.xbongbong.saas.model.ContactUserModel;
import com.xbongbong.saas.model.ContractUserModel;
import com.xbongbong.saas.model.CustomerFocusModel;
import com.xbongbong.saas.model.CustomerModel;
import com.xbongbong.saas.model.CustomerUserModel;
import com.xbongbong.saas.model.InstockModel;
import com.xbongbong.saas.model.InventoryModel;
import com.xbongbong.saas.model.OpportunityUserModel;
import com.xbongbong.saas.model.OutstockModel;
import com.xbongbong.saas.model.PayPlanSheetUserModel;
import com.xbongbong.saas.model.PaymentBalanceUserModel;
import com.xbongbong.saas.model.PaymentSheetUserModel;
import com.xbongbong.saas.model.PaymentUserModel;
import com.xbongbong.saas.model.QuotationUserModel;
import com.xbongbong.saas.model.RefundUserModel;
import com.xbongbong.saas.model.ReturnedPurchaseModel;
import com.xbongbong.saas.model.TransferModel;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.UserModel;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.support.WriteRequest;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

@Component
@Slf4j
public class TeamDataHelp {

    @Resource
    private TeamDataFactory teamDataFactory;
    @Resource
    private TeamDataBusinessHelp teamDataBusinessHelp;
    @Resource
    private ContractUserModel contractUserModel;
    @Resource
    private CustomerUserModel customerUserModel;
    @Resource
    private FormTeamSetHelp formTeamSetHelp;
    @Resource
    private OpportunityUserModel opportunityUserModel;
    @Resource
    private ContactUserModel contactUserModel;
    @Resource
    private QuotationUserModel quotationUserModel;
    @Resource
    private PaymentBalanceUserModel paymentBalanceUserModel;
    @Resource
    private ClueUserModel clueUserModel;
    @Resource
    private RefundUserModel refundUserModel;
    @Resource
    private PaymentUserModel paymentUserModel;
    @Resource
    private CustomerModel customerModel;
    @Resource
    private CustomerFocusModel customerFocusModel;
    @Resource
    private PaymentSheetUserModel paymentSheetUserModel;
    @Resource
    private EsHelper esHelper;
    @Resource
    private BusinessUserTeamHelp businessUserTeamHelp;
    @Resource
    private ReturnedPurchaseModel returnedPurchaseModel;
    @Resource
    private AssembleModel assembleModel;
    @Resource
    private InstockModel instockModel;
    @Resource
    private OutstockModel outstockModel;
    @Resource
    private InventoryModel inventoryModel;
    @Resource
    private TransferModel transferModel;
    @Resource
    private UserModel userModel;
    @Resource
    private DynamicStrategyFactory dynamicStrategyFactory;
    @Resource
    private CrmTeamPermissionHelp crmTeamPermissionHelp;
    @Resource
    private PayPlanSheetUserModel payPlanSheetUserModel;
    @Resource
    private FormDataHelp formDataHelp;

    /**
     * 团队保存
     * @author 魏荣杰
     *
     */
    public List<TeamBatchPojo> save(TeamVerifyDTO teamVerifyDTO) throws XbbException {
        Integer businessType = teamVerifyDTO.getBusinessType();
        TeamStrategy teamStrategy = teamDataFactory.getStrategy(businessType, teamVerifyDTO.getDistributorMark(), teamVerifyDTO.getSaasMark());
        TeamAfterVerifyDTO teamAfterVerifyDTO = new TeamAfterVerifyDTO();
        try {
            // 封装校验
            teamAfterVerifyDTO = teamStrategy.verify(teamVerifyDTO);

            businessSave(teamAfterVerifyDTO);

            // api回调处理
            teamDataBusinessHelp.apiCallBack(teamVerifyDTO.getDataId(), businessType, teamVerifyDTO.getCorpid());
        } catch (Exception e) {
            log.info("非业务逻辑层的保存团队报错:{}", e);
            throw new XbbException(UserTeamErrorCodeEnum.API_ERROR_271004.getCode(), UserTeamErrorCodeEnum.API_ERROR_271004.getMsg());
        } finally {
            List<TeamBatchPojo> teamBatchPojos = teamAfterVerifyDTO.getTeamBatchPojos();
            if (!Objects.equals(teamVerifyDTO.getBatchTag(), BasicConstant.ONE) && CollectionsUtil.isNotEmpty(teamBatchPojos)) {
                throw new XbbException(teamBatchPojos.get(0).getCode(), teamBatchPojos.get(0).getFailMsgReason());
            }
            if (CollectionsUtil.isNotEmpty(teamAfterVerifyDTO.getTeamBatchPojos())) {
                return teamAfterVerifyDTO.getTeamBatchPojos();
            } else {
                return new ArrayList<>();
            }
        }

    }

    /**
     * 这个方法是从TeamDataHelp.save方法拆出来的，为啥要拆？
     * （1）详情页团队新增成员的时候是不需要考虑审批情况，所以校验、保存是可以放在一套的
     * （2）从我们主业务的新增、编辑进行团队成员的新增、删除的时候，需要清晰的拆分出beforeSave->save->afterSave
     *
     * @param teamAfterVerifyDTO
     * @throws XbbException
     */
    public void businessSave(TeamAfterVerifyDTO teamAfterVerifyDTO) throws XbbException {
        Integer businessType = teamAfterVerifyDTO.getBusinessType();
        TeamStrategy teamStrategy = teamDataFactory.getStrategy(businessType, teamAfterVerifyDTO.getDistributorMark(), teamAfterVerifyDTO.getSaasMark());
        teamAfterVerifyDTO = teamStrategy.specialVerify(teamAfterVerifyDTO);

        // 团队保存
        teamStrategy.save(teamAfterVerifyDTO);
        //如果是工作流的话就不需要走下面步骤
        TeamSaveMiddlePojo teamSaveMiddlePojo = teamAfterVerifyDTO.getTeamSaveMiddlePojo();
        if (Objects.isNull(teamSaveMiddlePojo) || Objects.equals(teamSaveMiddlePojo.getWorkFlowTag(), false)) {
            // 后续默认业务处理
//            if (Objects.equals(teamAfterVerifyDTO.getFromDetail(), true)) {
            if (!Objects.equals(teamAfterVerifyDTO.getIsImport(), BasicConstant.ONE)) {
                teamStrategy.afterSave(teamAfterVerifyDTO);
            }
//            }
            // 日志/消息（异步）
            if (!Objects.equals(teamAfterVerifyDTO.getIsImport(), BasicConstant.ONE)) {
                //只有非导入才会记录日志
                teamStrategy.log(teamAfterVerifyDTO);
            }

            // 团队继承逻辑
            teamDataBusinessHelp.inheritanceSave(teamAfterVerifyDTO);

            // 动态
            if(!Boolean.TRUE.equals(teamAfterVerifyDTO.getFromCheckRepeatForm())) {
                TeamDynamicStrategy teamDynamicStrategy = dynamicStrategyFactory.getTeamDynamicStrategyByBusinessType(businessType);
                teamDynamicStrategy.dynamic(DynamicTeamDTO.initDynamicTeamDTO(teamAfterVerifyDTO));
            }
        }


    }

    /**
     * 合并客户进行团队操作，因为跟我们底层的通用逻辑还是有差，不写太多特殊逻辑，就单独抽个方法进行处理
     *
     *
     * @param teamAfterVerifyDTO
     * @throws XbbException
     */
    public void isolationMergeCustomerSave(TeamAfterVerifyDTO teamAfterVerifyDTO, Long delId) throws XbbException {
        Integer businessType = teamAfterVerifyDTO.getBusinessType();
        TeamStrategy teamStrategy = teamDataFactory.getStrategy(businessType, teamAfterVerifyDTO.getDistributorMark(), teamAfterVerifyDTO.getSaasMark());
        teamAfterVerifyDTO = teamStrategy.specialVerify(teamAfterVerifyDTO);
        // 团队保存
        mergeCustomerSaveTeam(teamAfterVerifyDTO, delId);
        //如果是工作流的话就不需要走下面步骤
        TeamSaveMiddlePojo teamSaveMiddlePojo = teamAfterVerifyDTO.getTeamSaveMiddlePojo();
        if (Objects.isNull(teamSaveMiddlePojo) || Objects.equals(teamSaveMiddlePojo.getWorkFlowTag(), false)) {
            // 后续默认业务处理
            if (Objects.equals(teamAfterVerifyDTO.getFromDetail(), true)) {
                teamStrategy.afterSave(teamAfterVerifyDTO);
            }
            // 日志/消息（异步）
            if (!Objects.equals(teamAfterVerifyDTO.getIsImport(), BasicConstant.ONE)) {
                //只有非导入才会记录日志
                teamStrategy.log(teamAfterVerifyDTO);

                // 动态
                TeamDynamicStrategy teamDynamicStrategy = dynamicStrategyFactory.getTeamDynamicStrategyByBusinessType(businessType);
                teamDynamicStrategy.dynamic(DynamicTeamDTO.initDynamicTeamDTO(teamAfterVerifyDTO));
            }
        }
    }

    /**
     * 合并客户保存团队,这边只需要更新一下更新时间，以及更新一下团队中用户对应的dataId
     *
     * @param teamAfterVerifyDTO
     */
    private void mergeCustomerSaveTeam(TeamAfterVerifyDTO teamAfterVerifyDTO, Long delId) throws XbbException {
        List<Long> dataId = teamAfterVerifyDTO.getDataId();
        //先把原先下面的负责团队给删除掉，然后拼接成
        customerUserModel.batchDeleteByCustomerId(teamAfterVerifyDTO.getCorpid(), dataId, null);
        List<CustomerUserEntity> customerUserEntityList = customerUserModel.getByCustomerId(teamAfterVerifyDTO.getCorpid(), delId);
        customerUserEntityList.forEach(customerUserEntity -> {
            customerUserEntity.setId(null);
            customerUserEntity.setDataId(dataId.get(BasicConstant.ZERO));
            customerUserEntity.setUpdateTime(DateTimeUtil.getInt());
        });
        customerUserModel.insertBatch(customerUserEntityList, false);
    }

    /**
     * tab栏详情信息
     *
     * @return
     */
    public TeamDetailVO detail(TeamDetailDTO teamDetailDTO) throws XbbException {
        TeamDetailShareVO teamDetailShareVO = noTeamBusinessDetail(teamDetailDTO);
        if (Objects.nonNull(teamDetailShareVO)) {
            return teamDetailShareVO;
        }
        TeamStrategy teamStrategy = teamDataFactory.getStrategy(teamDetailDTO.getBusinessType(), teamDetailDTO.getDistributorMark(), teamDetailDTO.getSaasMark());
        return teamStrategy.detail(teamDetailDTO);
    }

    /**
     * 没有团队业务的详情返回
     *
     * @param teamDetailDTO 详情入参
     */
    private TeamDetailShareVO noTeamBusinessDetail(TeamDetailDTO teamDetailDTO) {
        Integer businessType = teamDetailDTO.getBusinessType();
        Long dataId = teamDetailDTO.getDataId();
        String corpid = teamDetailDTO.getCorpid();
        Integer saasMark = teamDetailDTO.getSaasMark();
        UserVO loginUser = teamDetailDTO.getLoginUser();
        RedundantTemplateTypeEnum redundantTemplateTypeEnum = RedundantTemplateTypeEnum.getByCode(businessType);
        switch (redundantTemplateTypeEnum) {
            case RETURNED_PURCHASE:
                ReturnedPurchaseEntityExt purchaseEntityExt = returnedPurchaseModel.getByKey(dataId, corpid);
                String ownerId = purchaseEntityExt.getOwnerId();
                return setNoTeamBusinessDetailVO(corpid, ownerId, saasMark, businessType, loginUser);
            case ASSEMBLE:
                AssembleEntityExt assembleEntityExt = assembleModel.getByKey(dataId, corpid);
                ownerId = assembleEntityExt.getOwnerId();
                return setNoTeamBusinessDetailVO(corpid, ownerId, saasMark, businessType, loginUser);
            case INSTOCK:
            case PURCHASE_INSTOCK:
            case REFUND_INSTOCK:
            case OTHER_INSTOCK:
            case PRODUCTION_INSTOCK:
            case RETURNED_MATERIEL_INSTOCK:
                InstockEntityExt instockEntityExt = instockModel.getByKey(dataId, corpid);
                ownerId = instockEntityExt.getOwnerId();
                return setNoTeamBusinessDetailVO(corpid, ownerId, saasMark, businessType, loginUser);
            case OUTSTOCK:
            case CONTRACT_OUTSTOCK:
            case RETURNED_PURCHASE_OUTSTOCK:
            case PRODUCTION_MATERIEL_OUTSTOCK:
            case OTHER_OUTSTOCK:
            case WORK_ORDER_OUTSTOCK:
                OutstockEntityExt outstockEntityExt = outstockModel.getByKey(dataId, corpid);
                ownerId = outstockEntityExt.getOwnerId();
                return setNoTeamBusinessDetailVO(corpid, ownerId, saasMark, businessType, loginUser);
            case INVENTORY:
                InventoryEntityExt inventoryEntityExt = inventoryModel.getByKey(dataId, corpid);
                ownerId = inventoryEntityExt.getOwnerId();
                return setNoTeamBusinessDetailVO(corpid, ownerId, saasMark, businessType, loginUser);
            case TRANSFER:
                TransferEntityExt transferEntityExt = transferModel.getByKey(dataId, corpid);
                ownerId = transferEntityExt.getOwnerId();
                return setNoTeamBusinessDetailVO(corpid, ownerId, saasMark, businessType, loginUser);
            default:
                break;
        }
        return null;
    }

    private TeamDetailShareVO setNoTeamBusinessDetailVO(String corpid, String userId, Integer saasMark, Integer businessType,UserVO loginUser) {
        TeamDetailShareVO teamDetailShareVO = new TeamDetailShareVO();
        List<String> userIdIn = new ArrayList<>();
        userIdIn.add(userId);
        List<UserEntity> userEntitys = userModel.getByUserIdIn(corpid, userIdIn, true);
        List<MainUserPojo> mainUserArr = new ArrayList<>();
        if (CollectionsUtil.isNotEmpty(userEntitys)) {
            UserEntity userEntity = userEntitys.get(0);
            TeamUserPojo teamUserPojo = new TeamUserPojo(-1L, userEntity.getUserId(), userEntity.getName(),
                    userEntity.getAvatar(), CoUserPermissionEnum.READ.getPermissionValue(), TeamMembersConstant.NO_FORM_PERMISSION, userEntity.getDel());
            MainUserPojo mainUserPojo = new MainUserPojo();
            mainUserPojo.setTeamUserPojo(teamUserPojo);
            mainUserArr.add(mainUserPojo);
        }
        teamDetailShareVO.setMainUserArr(mainUserArr);
        //权限的封装，现在这些无团队的权限封装，目前只需要封装移交按钮的权限
        boolean handoverPermission = true;
        HandoverPermissionAliasEnum handoverPermissionAlias = HandoverPermissionAliasEnum.getByCode(businessType);
        if (Objects.equals(saasMark, SaasMarkEnum.SAAS.getCode()) && !loginUser.getPermSet().contains(handoverPermissionAlias.getAlias())) {
            handoverPermission = false;
        }
        ShareUserPermissionPojo userPermissionPojo = new ShareUserPermissionPojo(false, false, false, false, false, false, handoverPermission);
        teamDetailShareVO.setUserPermissionPojo(userPermissionPojo);
        teamDetailShareVO.setNoCoUserTab(true);
        return teamDetailShareVO;
    }

    /**
     * 编辑团队成员协同人权限
     *
     * @param teamDetailUpdateDTO 团队详情更新操作相关的接收实体
     * @return
     */
    public TeamDetailEditCoPerVO editCoPermission(TeamDetailUpdateDTO teamDetailUpdateDTO) throws XbbException {
        TeamStrategy teamStrategy = teamDataFactory.getStrategy(teamDetailUpdateDTO.getBusinessType(), teamDetailUpdateDTO.getDistributorMark(), teamDetailUpdateDTO.getSaasMark());
        return teamStrategy.editCoPermission(teamDetailUpdateDTO);
    }

    /**
     * 编辑团队里面的成员标签
     *
     * @param teamDetailEditLabelDTO 编辑团队成员标签的接收实体
     * @return
     */
    public TeamDetailEditLabelVO editLabel(TeamDetailEditLabelDTO teamDetailEditLabelDTO) throws XbbException{
        TeamStrategy teamStrategy = teamDataFactory.getStrategy(teamDetailEditLabelDTO.getBusinessType(), teamDetailEditLabelDTO.getDistributorMark(), teamDetailEditLabelDTO.getSaasMark());
        return teamStrategy.editLabel(teamDetailEditLabelDTO);
    }


    /**
     * 获取业务列表中与团队有关的一些批量操作的权限
     *
     * @param formDataListDTO 列表实体
     * @param explains 列表表单解释
     *
     * @return
     */
    public TeamListBatchPermissionVO getTeamListBatchPermission(FormDataListDTO formDataListDTO, List<FieldAttrEntity> explains) throws XbbException{
        return crmTeamPermissionHelp.getTeamListBatchPermission(formDataListDTO, explains);
    }


    /**
     * Description:  新建编辑团队保存
     * @param saasNeedRedundantAttrPoJo
	 * @param dataId
     * @param newPaasFormDataEntity 主数据实体
     * @param isImport 1是导入
     * @return void
     * @throws
     * @author 魏荣杰
     * @date 2022/2/18 11:27
     * @since
     */
    public AfterSavePojo saveUserTeam(SaasNeedRedundantAttrPojo saasNeedRedundantAttrPoJo, Long dataId, PaasFormDataEntity newPaasFormDataEntity, Integer isImport, Boolean workflowTag) throws XbbException {
        AfterSavePojo afterSavePojo = new AfterSavePojo();
        Integer updateLine = BasicConstant.ZERO;
        if (Objects.nonNull(saasNeedRedundantAttrPoJo)) {
            TeamAfterVerifyDTO teamAfterVerifyDTO = saasNeedRedundantAttrPoJo.getTeamAfterVerifyDTO();
            if (Objects.nonNull(teamAfterVerifyDTO)) {
                teamAfterVerifyDTO.setDataId(new ArrayList<>(Arrays.asList(dataId)));
                //因为这边主业务成功了，所以能拿到主业务dataId,需要给key为null的map,重新赋值一下key
                Map<String, Set<String>> addMainUserMap = teamAfterVerifyDTO.getAddMainUserMap();
                Map<String, Set<String>> delMainUserMap = teamAfterVerifyDTO.getDelMainUserMap();
                Map<String, Set<String>> addCoUserMap = teamAfterVerifyDTO.getAddCoUserMap();
                Map<String, Set<String>> delCoUserMap = teamAfterVerifyDTO.getDelCoUserMap();
                Map<String, Set<String>> updateToMainUserMap = teamAfterVerifyDTO.getUpdateToMainUserMap();
                Map<String, Set<String>> updateToCoUserMap = teamAfterVerifyDTO.getUpdateToCoUserMap();
                updateLine = getLatestMap(addMainUserMap,dataId, updateLine);
                updateLine = getLatestMap(delMainUserMap,dataId, updateLine);
                updateLine = getLatestMap(addCoUserMap,dataId, updateLine);
                updateLine = getLatestMap(delCoUserMap,dataId, updateLine);
                updateLine = getLatestMap(updateToMainUserMap,dataId, updateLine);
                updateLine = getLatestMap(updateToCoUserMap,dataId, updateLine);
                TeamSaveMiddlePojo teamSaveMiddlePojo = new TeamSaveMiddlePojo();
                teamSaveMiddlePojo.setWorkFlowTag(workflowTag);
                teamAfterVerifyDTO.setTeamSaveMiddlePojo(teamSaveMiddlePojo);
                teamAfterVerifyDTO.setPaasFormDataEntity(newPaasFormDataEntity);
                teamAfterVerifyDTO.setIsImport(isImport);
                businessSave(teamAfterVerifyDTO);
                //因为可能会有些报错，但是不抛出，用于后续排查问题
                List<TeamBatchPojo> teamBatchPojos = teamAfterVerifyDTO.getTeamBatchPojos();
                if (CollectionsUtil.isNotEmpty(teamBatchPojos)) {
                    log.error("============保存团队异常==：{}", String.valueOf(teamBatchPojos));
                }
                if (Objects.equals(teamAfterVerifyDTO.getBusinessType(), XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode()) || Objects.equals(teamAfterVerifyDTO.getBusinessType(), XbbRefTypeEnum.CLUE.getCode())) {
                    List<UserTeamEntity> userTeamList = businessUserTeamHelp.getUserTeamList(Arrays.asList(dataId), teamAfterVerifyDTO.getCorpid(), teamAfterVerifyDTO.getBusinessType(), false);

                    List<UserTeamEntity> collect = userTeamList.stream().filter(v -> Objects.equals(v.getIsMain(), BasicConstant.ONE)).collect(Collectors.toList());
                    boolean haveTeam = CollectionsUtil.isNotEmpty(collect);
                    afterSavePojo.setHaveTeam(haveTeam);
                }
            }
        }

        afterSavePojo.setUpdateLine(updateLine);
        return afterSavePojo;
    }

    /**
     * 此方法单独saveUserTeam拆分出来savePayOrPaymentSheetUserTeam。
     * 主要是因为回款单有主子回款单，但是日志记录其实只会记录
     * 回款单只有新增功能，回款单编辑的时候一些核心字段是隐藏的。所以这边只会存在addMainList和addCouserList
     *
     * @param saasNeedRedundantAttrPoJo
     * @param newPaasFormDataEntity
     * @param isImport
     * @param sheetTag 单据标识 true:回款单标识 false:付款单标识
     */
    public AfterSavePojo savePayOrPaymentSheetUserTeam(SaasNeedRedundantAttrPojo saasNeedRedundantAttrPoJo, PaasFormDataEntity newPaasFormDataEntity, Integer isImport,
                                                       List<PaymentSheetEntityExt> paymentSheetList, List<PayPlanSheetEntityExt> paySheetList, Boolean workFlowTag, Boolean sheetTag) throws XbbException {
        AfterSavePojo afterSavePojo = new AfterSavePojo();
        if (Objects.nonNull(saasNeedRedundantAttrPoJo)) {

            Set<String> mainUserList = new HashSet<>();
            Set<String> coUserList = new HashSet<>();
            if (workFlowTag) {
                if (sheetTag) {
                    // 回款单
                    List<PaymentSheetUserEntity> paymentSheetUserIdList = paymentSheetUserModel.getPaymentSheetUserIdList(newPaasFormDataEntity.getCorpid(), newPaasFormDataEntity.getId(), null);
                    Map<Integer, List<PaymentSheetUserEntity>> collect = paymentSheetUserIdList.stream().collect(Collectors.groupingBy(PaymentSheetUserEntity::getIsMain));
                    if (!Objects.isNull(collect.get(BasicConstant.ONE))) {
                        mainUserList = collect.get(BasicConstant.ONE).stream().map(PaymentSheetUserEntity::getUserId).collect(Collectors.toSet());
                    }
                    if (!Objects.isNull(collect.get(BasicConstant.ZERO))) {
                        coUserList = collect.get(BasicConstant.ZERO).stream().map(PaymentSheetUserEntity::getUserId).collect(Collectors.toSet());
                    }
                } else {
                    // 付款单
                    List<PayPlanSheetUserEntity> paySheetUserIdList = payPlanSheetUserModel.getPaySheetUserIdList(newPaasFormDataEntity.getCorpid(), newPaasFormDataEntity.getId(), null);
                    Map<Integer, List<PayPlanSheetUserEntity>> collect = paySheetUserIdList.stream().collect(Collectors.groupingBy(PayPlanSheetUserEntity::getIsMain));
                    if (!Objects.isNull(collect.get(BasicConstant.ONE))) {
                        mainUserList = collect.get(BasicConstant.ONE).stream().map(PayPlanSheetUserEntity::getUserId).collect(Collectors.toSet());
                    }
                    if (!Objects.isNull(collect.get(BasicConstant.ZERO))) {
                        coUserList = collect.get(BasicConstant.ZERO).stream().map(PayPlanSheetUserEntity::getUserId).collect(Collectors.toSet());
                    }
                }
            }

            //根据回款单信息去做一个匹配
            TeamAfterVerifyDTO teamAfterVerifyDTO = saasNeedRedundantAttrPoJo.getTeamAfterVerifyDTO();
            Set<String> newAddMainUserList = new HashSet<>();
            Set<String> newAddCoUserList = new HashSet<>();
            //这是前端传进来所有的负责人和协同人，可能用户根据客户、合同的带出来的默认团队，用户已经修改过了
            Map<String, Set<String>> addMainUserMap = teamAfterVerifyDTO.getAddMainUserMap();
            Map<String, Set<String>> addCoUserMap = teamAfterVerifyDTO.getAddCoUserMap();
            String key = null;
            if (Objects.nonNull(addMainUserMap)) {
                for (Map.Entry<String, Set<String>> entry : addMainUserMap.entrySet()) {
                    key = entry.getKey();
                    newAddMainUserList = entry.getValue();
                }
            }
            if (Objects.nonNull(addCoUserMap)) {
                for (Map.Entry<String, Set<String>> entry : addCoUserMap.entrySet()) {
                    key = entry.getKey();
                    newAddCoUserList = entry.getValue();
                }
            }
            TeamSaveMiddlePojo teamSaveMiddlePojo = new TeamSaveMiddlePojo();
            List<Long> paymentSheetSonDataIdList = new ArrayList<>();
            List<Long> allDataIdList = new ArrayList<>();
            if (sheetTag) {
                //回款单
                for (PaymentSheetEntityExt paymentSheetEntity : paymentSheetList) {
                    Integer alone = paymentSheetEntity.getAlone();
                    Long dataId = paymentSheetEntity.getDataId();
                    addMainUserMap.put(String.valueOf(dataId), newAddMainUserList);
                    addCoUserMap.put(String.valueOf(dataId), newAddCoUserList);
                    if (Objects.equals(alone, SheetAloneEnum.CHILD.getCode())) {
                        paymentSheetSonDataIdList.add(dataId);
                        if (workFlowTag) {
                            addMainUserMap.put(String.valueOf(dataId), mainUserList);
                            addCoUserMap.put(String.valueOf(dataId), coUserList);
                        }
                    }
                    allDataIdList.add(dataId);
                }
            }else {
                //付款单
                for (PayPlanSheetEntityExt payPlanSheetEntityExt : paySheetList) {
                    Integer alone = payPlanSheetEntityExt.getAlone();
                    Long dataId = payPlanSheetEntityExt.getDataId();
                    addMainUserMap.put(String.valueOf(dataId), newAddMainUserList);
                    addCoUserMap.put(String.valueOf(dataId), newAddCoUserList);
                    if (Objects.equals(alone, SheetAloneEnum.CHILD.getCode())) {
                        paymentSheetSonDataIdList.add(dataId);
                        if (workFlowTag) {
                            addMainUserMap.put(String.valueOf(dataId), mainUserList);
                            addCoUserMap.put(String.valueOf(dataId), coUserList);
                        }
                    }
                    allDataIdList.add(dataId);
                }
            }
            if (CollectionsUtil.isNotEmpty(newAddCoUserList) || CollectionsUtil.isNotEmpty(newAddCoUserList)) {
                afterSavePojo.setUpdateLine(BasicConstant.ONE);
            }else {
                afterSavePojo.setUpdateLine(BasicConstant.ZERO);
            }
            addMainUserMap.remove(key);
            addCoUserMap.remove(key);
            teamSaveMiddlePojo.setWorkFlowTag(workFlowTag);
            teamSaveMiddlePojo.setPaymentSheetSonDataIdList(paymentSheetSonDataIdList);
            teamAfterVerifyDTO.setTeamSaveMiddlePojo(teamSaveMiddlePojo);
            teamAfterVerifyDTO.setPaasFormDataEntity(newPaasFormDataEntity);
            teamAfterVerifyDTO.setIsImport(isImport);
            teamAfterVerifyDTO.setDataId(allDataIdList);
            businessSave(teamAfterVerifyDTO);
        }
        return afterSavePojo;
    }

    /**
     * 用于批量操作应收款/付款计划主业务封装的实体
     *
     * @param payAndpaymentEntityExts
     * @param serialTeamMap
     * @throws XbbException
     */
    public <T> void savePayAndpaymentBatchBusUserTeam(List<T> payAndpaymentEntityExts, Map<String, AddMuchFieldPojo> serialTeamMap, UserVO loginUser) throws XbbException{
        TeamAfterVerifyDTO fininalTeamAfterVerfiDTO = new TeamAfterVerifyDTO();
        List<Long> paymentIdList = new ArrayList<>();
        Map<String, Set<String>> newAddMainUserMap = new HashMap<>();
        Map<String, Set<String>> newAddCoUserMap = new HashMap<>();
        Map<String, Set<String>> newDelMainUserMap = new HashMap<>();
        Map<String, Set<String>> newDelCoUserMap = new HashMap<>();
        Map<String, Set<String>> newUpdateToCoUserMap = new HashMap<>();
        Map<String, Set<String>> newUpdateToMainUserMap = new HashMap<>();
        //主要用于拷贝一些基础字段，比如formId, businessType之类的
        TeamAfterVerifyDTO copyFininalTeamAfterVerfiDTO = null;
        Map<Long, PaasFormDataEntity> paasFormDataEntityExtMap = new HashMap<>(payAndpaymentEntityExts.size() * BasicConstant.TWO);
        for (T t : payAndpaymentEntityExts) {
            PaasFormDataEntity paasFormDataEntity = new PaasFormDataEntity();
            BeanUtil.copyProperties(t, paasFormDataEntity);
            Long dataId = paasFormDataEntity.getDataId();
            paasFormDataEntityExtMap.put(dataId, paasFormDataEntity);
            paymentIdList.add(dataId);
            String paymentSerialNo = paasFormDataEntity.getSerialNo();
            AddMuchFieldPojo addMuchFieldPojo = serialTeamMap.get(paymentSerialNo);
            TeamAfterVerifyDTO teamAfterVerifyDTO = addMuchFieldPojo.getTeamAfterVerifyDTO();
            copyFininalTeamAfterVerfiDTO = teamAfterVerifyDTO;
            Map<String, Set<String>> addMainUserMap = teamAfterVerifyDTO.getAddMainUserMap();
            Map<String, Set<String>> addCoUserMap = teamAfterVerifyDTO.getAddCoUserMap();
            Map<String, Set<String>> delMainUserMap = teamAfterVerifyDTO.getDelMainUserMap();
            Map<String, Set<String>> delCoUserMap = teamAfterVerifyDTO.getDelCoUserMap();
            Map<String, Set<String>> updateToCoUserMap = teamAfterVerifyDTO.getUpdateToCoUserMap();
            Map<String, Set<String>> updateToMainUserMap = teamAfterVerifyDTO.getUpdateToMainUserMap();
            getBatchLatestMap(dataId, fininalTeamAfterVerfiDTO, addMainUserMap, addCoUserMap, delMainUserMap, delCoUserMap, updateToCoUserMap, updateToMainUserMap,
                    newAddMainUserMap, newAddCoUserMap, newDelMainUserMap, newDelCoUserMap, newUpdateToCoUserMap, newUpdateToMainUserMap);
        }
        BeanUtil.copyProperties(copyFininalTeamAfterVerfiDTO, fininalTeamAfterVerfiDTO);
        fininalTeamAfterVerfiDTO.setAddMainUserMap(newAddMainUserMap);
        fininalTeamAfterVerfiDTO.setAddCoUserMap(newAddCoUserMap);
        fininalTeamAfterVerfiDTO.setDelMainUserMap(newDelMainUserMap);
        fininalTeamAfterVerfiDTO.setDelCoUserMap(newDelCoUserMap);
        fininalTeamAfterVerfiDTO.setUpdateToCoUserMap(newUpdateToCoUserMap);
        fininalTeamAfterVerfiDTO.setUpdateToMainUserMap(newUpdateToMainUserMap);
        TeamSaveMiddlePojo teamSaveMiddlePojo = new TeamSaveMiddlePojo();
        teamSaveMiddlePojo.setWorkFlowTag(false);
        fininalTeamAfterVerfiDTO.setTeamSaveMiddlePojo(teamSaveMiddlePojo);
        fininalTeamAfterVerfiDTO.setIsImport(BasicConstant.ZERO);
        fininalTeamAfterVerfiDTO.setDataId(paymentIdList);
        fininalTeamAfterVerfiDTO.setPaasFormDataEntityExtMap(paasFormDataEntityExtMap);
        fininalTeamAfterVerfiDTO.setLoginUser(loginUser);
        businessSave(fininalTeamAfterVerfiDTO);
        //因为可能会有些报错，但是不抛出，用于后续排查问题
        List<TeamBatchPojo> teamBatchPojos = fininalTeamAfterVerfiDTO.getTeamBatchPojos();
        if (CollectionsUtil.isNotEmpty(teamBatchPojos)) {
            log.error("============保存团队异常==：{}", String.valueOf(teamBatchPojos));
        }
    }

    /**
     * 用于批量操作回款单主业务封装的实体
     *
     * @param payAndPaymentSheetEntityExtList 付款单或者回款单列表
     * @param serialTeamMap
     * @throws XbbException
     */
    public <T> void savePaymentSheetBatchBusUserTeam(List<T> payAndPaymentSheetEntityExtList, Map<String, AddMuchFieldPojo> serialTeamMap, UserVO loginUser) throws XbbException{
        TeamAfterVerifyDTO fininalTeamAfterVerfiDTO = new TeamAfterVerifyDTO();
        List<Long> paymentSheetIdList = new ArrayList<>();
        Map<String, Set<String>> newAddMainUserMap = new HashMap<>();
        Map<String, Set<String>> newAddCoUserMap = new HashMap<>();
        Map<String, Set<String>> newDelMainUserMap = new HashMap<>();
        Map<String, Set<String>> newDelCoUserMap = new HashMap<>();
        Map<String, Set<String>> newUpdateToCoUserMap = new HashMap<>();
        Map<String, Set<String>> newUpdateToMainUserMap = new HashMap<>();
        //主要用于拷贝一些基础字段，比如formId, businessType之类的
        TeamAfterVerifyDTO copyFininalTeamAfterVerfiDTO = null;
        Map<Long, PaasFormDataEntity> paasFormDataEntityExtMap = new HashMap<>(payAndPaymentSheetEntityExtList.size() * BasicConstant.TWO);
        for (T t : payAndPaymentSheetEntityExtList) {
            PaasFormDataEntity paasFormDataEntity = new PaasFormDataEntity();
            BeanUtil.copyProperties(t, paasFormDataEntity);
            Long dataId = paasFormDataEntity.getDataId();
            paasFormDataEntityExtMap.put(dataId, paasFormDataEntity);
            paymentSheetIdList.add(dataId);
            String paymentSheetSerialNo = paasFormDataEntity.getSerialNo();
            AddMuchFieldPojo addMuchFieldPojo = serialTeamMap.get(paymentSheetSerialNo);
            TeamAfterVerifyDTO teamAfterVerifyDTO = addMuchFieldPojo.getTeamAfterVerifyDTO();
            copyFininalTeamAfterVerfiDTO = teamAfterVerifyDTO;
            Map<String, Set<String>> addMainUserMap = teamAfterVerifyDTO.getAddMainUserMap();
            Map<String, Set<String>> addCoUserMap = teamAfterVerifyDTO.getAddCoUserMap();
            Map<String, Set<String>> delMainUserMap = teamAfterVerifyDTO.getDelMainUserMap();
            Map<String, Set<String>> delCoUserMap = teamAfterVerifyDTO.getDelCoUserMap();
            Map<String, Set<String>> updateToCoUserMap = teamAfterVerifyDTO.getUpdateToCoUserMap();
            Map<String, Set<String>> updateToMainUserMap = teamAfterVerifyDTO.getUpdateToMainUserMap();
            getBatchLatestMap(dataId, fininalTeamAfterVerfiDTO, addMainUserMap, addCoUserMap, delMainUserMap, delCoUserMap, updateToCoUserMap, updateToMainUserMap,
                    newAddMainUserMap, newAddCoUserMap, newDelMainUserMap, newDelCoUserMap, newUpdateToCoUserMap, newUpdateToMainUserMap);
        }
        BeanUtil.copyProperties(copyFininalTeamAfterVerfiDTO, fininalTeamAfterVerfiDTO);
        fininalTeamAfterVerfiDTO.setAddMainUserMap(newAddMainUserMap);
        fininalTeamAfterVerfiDTO.setAddCoUserMap(newAddCoUserMap);
        fininalTeamAfterVerfiDTO.setDelMainUserMap(newDelMainUserMap);
        fininalTeamAfterVerfiDTO.setDelCoUserMap(newDelCoUserMap);
        fininalTeamAfterVerfiDTO.setUpdateToCoUserMap(newUpdateToCoUserMap);
        fininalTeamAfterVerfiDTO.setUpdateToMainUserMap(newUpdateToMainUserMap);
        TeamSaveMiddlePojo teamSaveMiddlePojo = new TeamSaveMiddlePojo();
        teamSaveMiddlePojo.setWorkFlowTag(false);
        fininalTeamAfterVerfiDTO.setTeamSaveMiddlePojo(teamSaveMiddlePojo);
        fininalTeamAfterVerfiDTO.setIsImport(BasicConstant.ZERO);
        fininalTeamAfterVerfiDTO.setDataId(paymentSheetIdList);
        fininalTeamAfterVerfiDTO.setPaasFormDataEntityExtMap(paasFormDataEntityExtMap);
        businessSave(fininalTeamAfterVerfiDTO);
        //因为可能会有些报错，但是不抛出，用于后续排查问题
        List<TeamBatchPojo> teamBatchPojos = fininalTeamAfterVerfiDTO.getTeamBatchPojos();
        if (CollectionsUtil.isNotEmpty(teamBatchPojos)) {
            log.error("============保存团队异常==：{}", String.valueOf(teamBatchPojos));
        }
    }

    /**
     * 用于批量操作主业务封装的实体
     *
     * @param batchEntitys
     * @param virtualAndMainMap
     * @throws XbbException
     */
    public <T> void saveBatchBusUserTeam(List<T> batchEntitys, Map<String, TeamAfterVerifyDTO> virtualAndMainMap, Integer isImport, UserVO loginUser) throws XbbException{
        TeamAfterVerifyDTO fininalTeamAfterVerfiDTO = new TeamAfterVerifyDTO();
        List<Long> dataIdList = new ArrayList<>();
        Map<String, Set<String>> newAddMainUserMap = new HashMap<>();
        Map<String, Set<String>> newAddCoUserMap = new HashMap<>();
        Map<String, Set<String>> newDelMainUserMap = new HashMap<>();
        Map<String, Set<String>> newDelCoUserMap = new HashMap<>();
        Map<String, Set<String>> newUpdateToCoUserMap = new HashMap<>();
        Map<String, Set<String>> newUpdateToMainUserMap = new HashMap<>();
        //主要用于拷贝一些基础字段，比如formId, businessType之类的
        TeamAfterVerifyDTO copyFininalTeamAfterVerfiDTO = null;
        Map<Long, PaasFormDataEntity> paasFormDataEntityExtMap = new HashMap<>(batchEntitys.size() * BasicConstant.TWO);
        for (T t : batchEntitys) {
            PaasFormDataEntity paasFormDataEntity = new PaasFormDataEntity();
            BeanUtil.copyProperties(t, paasFormDataEntity);
            Long dataId = paasFormDataEntity.getDataId();
            paasFormDataEntityExtMap.put(dataId, paasFormDataEntity);
            dataIdList.add(dataId);
            TeamAfterVerifyDTO teamAfterVerifyDTO = virtualAndMainMap.get(paasFormDataEntity.getUuid());
            copyFininalTeamAfterVerfiDTO = teamAfterVerifyDTO;
            Map<String, Set<String>> addMainUserMap = teamAfterVerifyDTO.getAddMainUserMap();
            Map<String, Set<String>> addCoUserMap = teamAfterVerifyDTO.getAddCoUserMap();
            Map<String, Set<String>> delMainUserMap = teamAfterVerifyDTO.getDelMainUserMap();
            Map<String, Set<String>> delCoUserMap = teamAfterVerifyDTO.getDelCoUserMap();
            Map<String, Set<String>> updateToCoUserMap = teamAfterVerifyDTO.getUpdateToCoUserMap();
            Map<String, Set<String>> updateToMainUserMap = teamAfterVerifyDTO.getUpdateToMainUserMap();
            getBatchLatestMap(dataId, fininalTeamAfterVerfiDTO, addMainUserMap, addCoUserMap, delMainUserMap, delCoUserMap, updateToCoUserMap, updateToMainUserMap,
                    newAddMainUserMap, newAddCoUserMap, newDelMainUserMap, newDelCoUserMap, newUpdateToCoUserMap, newUpdateToMainUserMap);
        }
        BeanUtil.copyProperties(copyFininalTeamAfterVerfiDTO, fininalTeamAfterVerfiDTO);
        fininalTeamAfterVerfiDTO.setAddMainUserMap(newAddMainUserMap);
        fininalTeamAfterVerfiDTO.setAddCoUserMap(newAddCoUserMap);
        fininalTeamAfterVerfiDTO.setDelMainUserMap(newDelMainUserMap);
        fininalTeamAfterVerfiDTO.setDelCoUserMap(newDelCoUserMap);
        fininalTeamAfterVerfiDTO.setUpdateToCoUserMap(newUpdateToCoUserMap);
        fininalTeamAfterVerfiDTO.setUpdateToMainUserMap(newUpdateToMainUserMap);
        TeamSaveMiddlePojo teamSaveMiddlePojo = new TeamSaveMiddlePojo();
        teamSaveMiddlePojo.setWorkFlowTag(false);
        fininalTeamAfterVerfiDTO.setTeamSaveMiddlePojo(teamSaveMiddlePojo);
        fininalTeamAfterVerfiDTO.setIsImport(isImport);
        fininalTeamAfterVerfiDTO.setDataId(dataIdList);
        fininalTeamAfterVerfiDTO.setPaasFormDataEntityExtMap(paasFormDataEntityExtMap);
        fininalTeamAfterVerfiDTO.setLoginUser(loginUser);
        businessSave(fininalTeamAfterVerfiDTO);
        //因为可能会有些报错，但是不抛出，用于后续排查问题
        List<TeamBatchPojo> teamBatchPojos = fininalTeamAfterVerfiDTO.getTeamBatchPojos();
        if (CollectionsUtil.isNotEmpty(teamBatchPojos)) {
            log.error("============保存团队异常==：{}", String.valueOf(teamBatchPojos));
        }
    }

    /**
     *
     *
     * 获取最新的map,主要到这一步有dataId了，所以用dataId替换空的key
     * 之所以需要有返回值是因为老哥那边
     *
     * @param map
     */
    private Integer getLatestMap(Map<String, Set<String>> map, Long dataId, Integer updateLine) {
        if (Objects.nonNull(map)) {
            String key = null;
            Set<String> value = null;
            for (Map.Entry<String, Set<String>> entry : map.entrySet()) {
                key = entry.getKey();
                value = entry.getValue();
            }
            map.remove(key);
            map.put(String.valueOf(dataId), value);
            if (CollectionsUtil.isNotEmpty(value) && Objects.equals(updateLine, BasicConstant.ZERO)) {
                updateLine = BasicConstant.ONE;
            }
        }
        return updateLine;
    }

    /**
     *
     *
     * 获取最新的map,主要到这一步有dataId了，所以用dataId替换空的key
     * 之所以需要有返回值是因为老哥那边
     *
     * @param
     */
    private void getBatchLatestMap(Long dataId, TeamAfterVerifyDTO fininalTeamAfterVerfiDTO,
                                   Map<String, Set<String>> addMainUserMap, Map<String, Set<String>> addCoUserMap,
                                   Map<String, Set<String>> delMainUserMap, Map<String, Set<String>> delCoUserMap,
                                   Map<String, Set<String>> updateToCoUserMap, Map<String, Set<String>> updateToMainUserMap,
                                   Map<String, Set<String>> newAddMainUserMap, Map<String, Set<String>> newAddCoUserMap,
                                   Map<String, Set<String>> newDelMainUserMap, Map<String, Set<String>> newDelCoUserMap,
                                   Map<String, Set<String>> newUpdateToCoUserMap, Map<String, Set<String>> newUpdateToMainUserMap) {
        if (Objects.nonNull(addMainUserMap)) {
            String key = null;
            Set<String> mainAddValue = null;
            Set<String> mainDelValue = null;
            Set<String> coAddValue = null;
            Set<String> coDelValue = null;
            Set<String> updateToCoValue = null;
            Set<String> updateToMainValue = null;
            for (Map.Entry<String, Set<String>> entry : addMainUserMap.entrySet()) {
                key = entry.getKey();
                mainAddValue = addMainUserMap.get(key);
                newAddMainUserMap.put(String.valueOf(dataId), mainAddValue);
                mainDelValue = delMainUserMap.get(key);
                newDelMainUserMap.put(String.valueOf(dataId), mainDelValue);
                coAddValue = addCoUserMap.get(key);
                newAddCoUserMap.put(String.valueOf(dataId), coAddValue);
                coDelValue = delCoUserMap.get(key);
                newDelCoUserMap.put(String.valueOf(dataId), coDelValue);
                updateToCoValue = updateToCoUserMap.get(key);
                newUpdateToCoUserMap.put(String.valueOf(dataId), updateToCoValue);
                updateToMainValue = updateToMainUserMap.get(key);
                newUpdateToMainUserMap.put(String.valueOf(dataId), updateToMainValue);
            }
        }
    }

    /**
     * @param
     * @Description: 客户、线索回退公海池解散团队
     * @return: void
     * @Author: shen.yang
     * @Date: 2022/3/9  19:01
     */
    public void disbandedTeam(String corpid, Long formId, Integer saasMark, Integer businessType, Integer distributorMark, List<Long> dataIdList, UpdateCustomerTeamScenesEnum updateCustomerTeamScenesEnum) throws XbbException {
        disbandedTeam(corpid,formId,saasMark,businessType,distributorMark,dataIdList,updateCustomerTeamScenesEnum,null);
    }

    /**
     * @param
     * @Description: 客户、线索回退公海池解散团队
     * @return: void
     * @Author: shen.yang
     * @Date: 2022/3/9  19:01
     */
    public void disbandedTeam(String corpid, Long formId, Integer saasMark, Integer businessType, Integer distributorMark, List<Long> dataIdList, UpdateCustomerTeamScenesEnum updateCustomerTeamScenesEnum, WriteRequest.RefreshPolicy refreshPolicy) throws XbbException {
        //查询设置
        FormTeamSetEntity formTeamSet = formTeamSetHelp.getFormTeamSet(corpid, formId, saasMark, businessType, distributorMark);
        Integer publicSwitch = formTeamSet.getPublicSwitch();
        if(Objects.equals(updateCustomerTeamScenesEnum,UpdateCustomerTeamScenesEnum.USER_LEAVE)){
            //如果是离职的，下游退回逻辑不用走公海池开关，走老逻辑
            //客户回退公海池老逻辑
            customerUserModel.disbandedTeam(corpid, dataIdList, refreshPolicy);
            //联系人、合同、报价单、机会、预收款
            contractUserModel.disbandedTeamByCustomerId(corpid, dataIdList);
            opportunityUserModel.disbandedTeamByCustomerId(corpid, dataIdList);
            contactUserModel.disbandedTeamByCustomerId(corpid, dataIdList);
            quotationUserModel.disbandedTeamByCustomerId(corpid, dataIdList);
            paymentBalanceUserModel.disbandedTeamByCustomerId(corpid, dataIdList);
            return;
        }

        if (Objects.equals(businessType, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode())) {
            //客户
            customerUserModel.disbandedTeam(corpid, dataIdList, refreshPolicy);
            //预收款是默认继承的不可修改，也直接解散
            paymentBalanceUserModel.disbandedTeamByCustomerId(corpid, dataIdList);
            if (Objects.equals(formTeamSet.getModel(), FormPatternEnum.FORM_ISOLATION.getModel())) {
                //隔离的下游不用同步解散
                return;
            }
            //共享的如果开关没勾选则走老逻辑，勾选了则按继承表单来
            if(Objects.equals(publicSwitch, Constant.ONE)){
                if (!Objects.isNull(formTeamSet.getLinkForm())) {
                    List<TeamLinkPOJO> teamLinkPOJOS = JSON.parseArray(JSON.toJSONString(formTeamSet.getLinkForm()), TeamLinkPOJO.class);
                    for (TeamLinkPOJO teamLinkPOJO : teamLinkPOJOS) {
                        XbbRefTypeEnum xbbRefTypeEnum = XbbRefTypeEnum.getByCode(teamLinkPOJO.getLinkBusinessType());
                        switch (xbbRefTypeEnum) {
                            case CONTRACT:
                                contractUserModel.disbandedTeamByCustomerId(corpid, dataIdList);
                                break;
                            case CONTACT:
                                contactUserModel.disbandedTeamByCustomerId(corpid, dataIdList);
                                break;
                            case QUOTATION:
                                quotationUserModel.disbandedTeamByCustomerId(corpid, dataIdList);
                                break;
                            case SALES_OPPORTUNITY:
                                opportunityUserModel.disbandedTeamByCustomerId(corpid, dataIdList);
                                break;
                            case PAYMENT:
                                paymentUserModel.disbandedTeamByCustomerId(corpid, dataIdList);
                                break;
                            case REFUND:
                                refundUserModel.disbandedTeamByCustomerId(corpid, dataIdList);
                                break;
                            case PAYMENT_SHEET:
                                //查出该客户所有的回款单
                                BoolQueryBuilder boolQueryBuilder = boolQuery();
                                List<String> fieldList = Collections.singletonList(FieldTypeEnum.DATAID.getAlias());
                                boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
                                boolQueryBuilder.filter(termQuery(ParameterConstant.DEL, DelEnum.NORMAL.getDel()));
                                boolQueryBuilder.filter(termsQuery("data." + PaymentSheetEnum.CUSTOMER_ID.getAttr() + ".keyword", dataIdList));
                                List<PaasFormDataEntityExt> paasFormDataList = esHelper.findByScroll(IndexTypeEnum.IDX_SAAS_PAYMENT_SHEET, boolQueryBuilder, PaasFormDataEntityExt.class, fieldList);
                                if(CollectionsUtil.isNotEmpty(paasFormDataList)){
                                    paymentSheetUserModel.disbandedTeamByCustomerId(corpid, paasFormDataList.stream().map(PaasFormDataEntityExt::getDataId).collect(Collectors.toList()));
                                }
                            default:
                                break;
                        }
                    }
                }
            }else{
                //联系人、合同、报价单、机会
                contractUserModel.disbandedTeamByCustomerId(corpid, dataIdList);
                opportunityUserModel.disbandedTeamByCustomerId(corpid, dataIdList);
                contactUserModel.disbandedTeamByCustomerId(corpid, dataIdList);
                quotationUserModel.disbandedTeamByCustomerId(corpid, dataIdList);
            }
        }else if(Objects.equals(businessType, XbbRefTypeEnum.CLUE.getCode())){
            //线索  线索没有下游了，不用走继承逻辑
            clueUserModel.disbandedTeam(corpid, dataIdList, refreshPolicy);
        }
    }

    /**
     *
     * @Description: 回退公海池、离职、捞取等，更新团队操作
     * @param
     * @return: void
     * @Author: shen.yang
     * @Date: 2022/3/15  14:30
    */
    public void batchUpdateTeam(TeamAfterVerifyDTO teamAfterVerifyDTO) throws XbbException {
        TeamStrategy teamStrategy = teamDataFactory.getStrategy(teamAfterVerifyDTO.getBusinessType(), teamAfterVerifyDTO.getDistributorMark(), teamAfterVerifyDTO.getSaasMark());
        // 团队继承逻辑
        // 团队保存
        teamStrategy.save(teamAfterVerifyDTO);
        //需要移除掉已经异常的dataId
        List<TeamBatchPojo> teamBatchPojos = teamAfterVerifyDTO.getTeamBatchPojos();
        List<Long> existTeamBatchIdList = new ArrayList<>();
        if (CollectionsUtil.isNotEmpty(teamBatchPojos)) {
            existTeamBatchIdList = teamBatchPojos.stream().map(TeamBatchPojo::getDataId).collect(Collectors.toList());
        }
        if (CollectionsUtil.isNotEmpty(existTeamBatchIdList) && CollectionsUtil.isNotEmpty(teamAfterVerifyDTO.getDataId())) {
            teamAfterVerifyDTO.getDataId().removeAll(existTeamBatchIdList);
        }
        teamStrategy.afterSave(teamAfterVerifyDTO);
        List<Long> dataId = teamAfterVerifyDTO.getDataId();
        List<Long> dataIdCopy = new ArrayList<>(dataId);
        teamAfterVerifyDTO.setDataId(dataIdCopy);
        teamDataBusinessHelp.inheritanceSave(teamAfterVerifyDTO);
    }

    /**
     *
     * @Description: 公海池操作，先校验，返回结果，后续操作异步完成
     * @param teamUpdateMidPOJO
     * @return: com.xbongbong.pro.team.TeamAfterVerifyDTO
     * @Author: shen.yang
     * @Date: 2022/3/22  13:58
    */
    public TeamAfterVerifyDTO publicVerify(TeamUpdateMidPOJO teamUpdateMidPOJO, Boolean isBack) throws XbbException {
        String corpid = teamUpdateMidPOJO.getCorpid();
        Integer businessType = teamUpdateMidPOJO.getBusinessType();
        Long formId = teamUpdateMidPOJO.getFormId();
        Integer saasMark = teamUpdateMidPOJO.getSaasMark();
        Integer distributorMark = teamUpdateMidPOJO.getDistributorMark();
        //查询设置
        FormTeamSetEntity formTeamSet = formTeamSetHelp.getFormTeamSet(corpid, formId, saasMark, businessType, distributorMark);
        //只有回退公海池需要走开关
        Integer publicSwitch = isBack ? formTeamSet.getPublicSwitch() : null;
        return basicVerify(teamUpdateMidPOJO, publicSwitch);
    }

    /**
     * Description: 团队基础校验封装
     * @param teamUpdateMidPOJO
	 * @param publicSwitch 公海池开关
     * @return com.xbongbong.pro.team.TeamAfterVerifyDTO
     * @throws
     * @author 魏荣杰
     * @date 2022/3/22 18:38
     * @since
     */
    public TeamAfterVerifyDTO basicVerify(TeamUpdateMidPOJO teamUpdateMidPOJO, Integer publicSwitch) throws XbbException {
        String corpid = teamUpdateMidPOJO.getCorpid();
        Integer businessType = teamUpdateMidPOJO.getBusinessType();
        Long formId = teamUpdateMidPOJO.getFormId();
        Integer saasMark = teamUpdateMidPOJO.getSaasMark();
        Integer distributorMark = teamUpdateMidPOJO.getDistributorMark();
        TeamVerifyDTO teamVerifyDTO = new TeamVerifyDTO();
        //因为都是走的增量操作，所以走FromDetail的校验
        teamVerifyDTO.setFromDetail(true);
        teamVerifyDTO.setIsInheritance(teamUpdateMidPOJO.getIsInheritance());
        teamVerifyDTO.setDataId(teamUpdateMidPOJO.getDataId());
        teamVerifyDTO.setCorpid(corpid);
        teamVerifyDTO.setFormId(formId);
        teamVerifyDTO.setOperateTag(teamUpdateMidPOJO.getOprateTag());
        teamVerifyDTO.setSaasMark(saasMark);
        teamVerifyDTO.setBusinessType(businessType);
        teamVerifyDTO.setDistributorMark(distributorMark);
        teamVerifyDTO.setIsNew(false);
        teamVerifyDTO.setNewAddMainUserList(teamUpdateMidPOJO.getNewAddMainUserList());
        teamVerifyDTO.setNewAddCoUserList(teamUpdateMidPOJO.getNewAddCoUserList());
        teamVerifyDTO.setNewDelMainUserList(teamUpdateMidPOJO.getNewDelMainUserList());
        teamVerifyDTO.setNewDelCoUserList(teamUpdateMidPOJO.getNewDelCoUserList());
        teamVerifyDTO.setFromBackPublic(teamUpdateMidPOJO.getFromBackPublic());
        teamVerifyDTO.setLoginUser(teamUpdateMidPOJO.getLoginUser());
        teamVerifyDTO.setUserId(teamUpdateMidPOJO.getLoginUser().getUserId());
        TeamStrategy teamStrategy = teamDataFactory.getStrategy(teamVerifyDTO.getBusinessType(), teamVerifyDTO.getDistributorMark(), saasMark);
        if(Objects.equals(publicSwitch, Constant.ZERO)){
            //公海池继承开关关闭，走老逻辑,相当于下游不继承
            teamVerifyDTO.setIsInheritance(true);
        }
        TeamAfterVerifyDTO teamAfterVerifyDTO = teamStrategy.verify(teamVerifyDTO);
        teamAfterVerifyDTO = teamStrategy.specialVerify(teamAfterVerifyDTO);
        return teamAfterVerifyDTO;
    }

    /**
     * Description: 团队操作锁前缀获取
     * @param saasMark
     * @param businessType
     * @return java.lang.String
     * @throws
     * @author 魏荣杰
     * @date 2022/5/16 18:59
     * @since
     */
    public String getRedisPrefix(Integer saasMark, Integer businessType) {
        String redisPrefix = null;
        if (Objects.equals(saasMark, SaasMarkEnum.SAAS.getCode())) {
            XbbRefTypeEnum business = XbbRefTypeEnum.getByCode(businessType);
            switch (business) {
                case CUSTOMER_MANAGEMENT:
                    redisPrefix = RedisPrefixConstant.CUSTOMER_LIST_BATCH;
                    break;
                case CONTRACT:
                    redisPrefix = RedisPrefixConstant.CONTRACT_LIST_BATCH;
                    break;
                case SALES_OPPORTUNITY:
                    redisPrefix = RedisPrefixConstant.OPPORTUNITY_LIST_BATCH;
                    break;
                case REFUND:
                    redisPrefix = RedisPrefixConstant.REFUND_LIST_BATCH;
                    break;
                case QUOTATION:
                    redisPrefix = RedisPrefixConstant.QUOTATION_LIST_BATCH;
                    break;
                case SUPPLIER:
                    redisPrefix = RedisPrefixConstant.SUPPLIER_LIST_BATCH;
                    break;
                case PURCHASE:
                    redisPrefix = RedisPrefixConstant.PURCHASE_LIST_BATCH;
                    break;
                case BOM_BILL:
                    redisPrefix = RedisPrefixConstant.BOM_LIST_BATCH;
                    break;
                case PRODUCTION_ORDER:
                    redisPrefix = RedisPrefixConstant.PRODUCTION_ORDER_LIST_BATCH;
                    break;
                case RETURNED_PURCHASE:
                    redisPrefix = RedisPrefixConstant.RETURN_PURCHASE_LIST_BATCH;
                    break;
                case ASSEMBLE:
                    redisPrefix = RedisPrefixConstant.ASSEMBLE_LIST_BATCH;
                    break;
                case PURCHASE_INSTOCK:
                    redisPrefix = RedisPrefixConstant.PURCHASE_INSTOCK_LIST_BATCH;
                    break;
                case REFUND_INSTOCK:
                    redisPrefix = RedisPrefixConstant.REFUND_INSTOCK_LIST_BATCH;
                    break;
                case OTHER_INSTOCK:
                    redisPrefix = RedisPrefixConstant.OTHER_OUTSTOCK_LIST_BATCH;
                    break;
                case PRODUCTION_INSTOCK:
                    redisPrefix = RedisPrefixConstant.PRODUCTION_INSTOCK_LIST_BATCH;
                    break;
                case RETURNED_MATERIEL_INSTOCK:
                    redisPrefix = RedisPrefixConstant.RETURNED_MATERIEL_INSTOCK_LIST_BATCH;
                    break;
                case CONTRACT_OUTSTOCK:
                    redisPrefix = RedisPrefixConstant.CONTRACT_OUTSTOCK_LIST_BATCH;
                    break;
                case RETURNED_PURCHASE_OUTSTOCK:
                    redisPrefix = RedisPrefixConstant.RETURNED_PURCHASE_OUTSTOCK_LIST_BATCH;
                    break;
                case PRODUCTION_MATERIEL_OUTSTOCK:
                    redisPrefix = RedisPrefixConstant.PRODUCTION_MATERIEL_OUTSTOCK_LIST_BATCH;
                    break;
                case OTHER_OUTSTOCK:
                    redisPrefix = RedisPrefixConstant.OTHER_OUTSTOCK_LIST_BATCH;
                    break;
                case WORK_ORDER_OUTSTOCK:
                    redisPrefix = RedisPrefixConstant.WORK_ORDER_OUTSTOCK_LIST_BATCH;
                    break;
                case TRANSFER:
                    redisPrefix = RedisPrefixConstant.TRANSFER_LIST_BATCH;
                    break;
                case INVENTORY:
                    redisPrefix = RedisPrefixConstant.INVENTORY_LIST_BATCH;
                    break;
                case PAAS:
                    redisPrefix = RedisPrefixConstant.PAAS_LIST_BATCH;
                    break;
                case WORK_ORDER:
                    redisPrefix = RedisPrefixConstant.WORK_ORDER_LIST_BATCH;
                    break;
                case CLUE:
                    redisPrefix = RedisPrefixConstant.CLUE_LIST_BATCH;
                    break;
                case MARKET_ACTIVITY:
                    redisPrefix = RedisPrefixConstant.MARKET_ACTIVITY_LIST_BATCH;
                    break;
                case COST_ADJUST:
                    redisPrefix = RedisPrefixConstant.COST_ADJUST_LIST_BATCH;
                    break;
                case PAYMENT_SHEET:
                    redisPrefix = RedisPrefixConstant.PAYMENT_SHEET_TEAM;
                    break;
                case PAY_SHEET:
                    redisPrefix = RedisPrefixConstant.PAY_SHEET_TEAM;
                    break;
                case PAYMENT:
                    redisPrefix = RedisPrefixConstant.PAYMENT_TEAM;
                    break;
                case PREPAY_BALANCE:
                    redisPrefix = RedisPrefixConstant.PREPAY_BALANCE_TEAM;
                    break;
                case PREPAYMENT_BALANCE:
                    redisPrefix = RedisPrefixConstant.PREPAYMENT_BALANCE_TEAM;
                    break;
                case PAY_PLAN:
                    redisPrefix = RedisPrefixConstant.PAY_PLAN_TEAM;
                    break;
                case CONTACT:
                    redisPrefix = RedisPrefixConstant.CONTACT_TEAM;
                    break;
                case SUPPLIER_CONTACT:
                    redisPrefix = RedisPrefixConstant.SUPPLIER_CONTACT_TEAM;
                    break;
                case WAREHOUSE:
                    redisPrefix = RedisPrefixConstant.WAREHOUSE_TEAM;
                    break;
                default:
                    break;
            }
        } else {
            redisPrefix = RedisPrefixConstant.PAAS_LIST_BATCH;
        }
        return redisPrefix;
    }
}
